//
//  CN_TableView.swift
//  Voice
//
//  Created by 卢逢卫 on 2024/3/5.
//

import UIKit

extension UITableView {
    // 初始化UITableView，并设置背景色、样式、分隔线样式、分隔线缩进、分隔线颜色和滚动指示器是否可见
    public static func cn_initWith(background: UIColor = .white, style: UITableView.Style, lineStyle: UITableViewCell.SeparatorStyle, lineInset: (left: CGFloat, right: CGFloat)?, lineColor: UIColor?, showsIndicator: Bool = false) -> UITableView {
        let tableView = UITableView(frame: .zero, style: style)
        tableView.backgroundColor = background
        tableView.separatorStyle = lineStyle
        if let lineInset = lineInset {
            tableView.separatorInset = UIEdgeInsets(top: 0, left: lineInset.left, bottom: 0, right: lineInset.right)
        }
        if let lineColor = lineColor {
            tableView.separatorColor = lineColor
        }
        tableView.showsVerticalScrollIndicator = showsIndicator
        return tableView
    }

    // 移除表格的表头视图
    public func cn_removeTableHeaderView() {
        tableHeaderView = nil
    }

    // 移除表格的表尾视图
    public func cn_removeTableFooterView() {
        tableFooterView = nil
    }

    // 刷新表格数据，并在刷新完成后执行闭包
    public func cn_reloadData(_ completion: @escaping () -> Void) {
        UIView.animate(withDuration: 0, animations: { self.reloadData() }, completion: { _ in completion() })
    }

    // 获取表格的总行数
    public func cn_numberOfRows() -> Int {
        var totalRows = 0
        for section in 0..<numberOfSections {
            totalRows += numberOfRows(inSection: section)
        }
        return totalRows
    }

    // 获取指定分区的最后一行的索引路径
    public func cn_indexPathForLastRow(inSection section: Int) -> IndexPath? {
        let numberOfRows = self.numberOfRows(inSection: section)
        guard numberOfRows > 0 else { return nil }
        return IndexPath(row: numberOfRows - 1, section: section)
    }

    // 注册 UITableViewCell 类型的单元格
    public func cn_registerCell<T>(cls: T.Type) where T: UITableViewCell {
        register(cls, forCellReuseIdentifier: String(describing: cls))
    }

    // 注册带标识符的 UITableViewCell 类型的单元格
    public func cn_registerCell<T>(cls: T.Type, withIdentifier identifier: String) where T: UITableViewCell {
        register(cls, forCellReuseIdentifier: identifier)
    }

    // 重用 UITableViewCell 类型的单元格
    public func cn_dequeueReusableCell<T>(cls: T.Type, for indexPath: IndexPath) -> T where T: UITableViewCell {
        guard let cell = dequeueReusableCell(withIdentifier: String(describing: cls), for: indexPath) as? T else {
            fatalError("Unable to dequeue cell with identifier: \(String(describing: cls))")
        }
        return cell
    }

    // 重用带标识符的 UITableViewCell 类型的单元格
    public func cn_dequeueReusableCell<T>(withIdentifier identifier: String, for indexPath: IndexPath) -> T where T: UITableViewCell {
        guard let cell = dequeueReusableCell(withIdentifier: identifier, for: indexPath) as? T else {
            fatalError("Unable to dequeue cell with identifier: \(identifier)")
        }
        return cell
    }

    // 注册 UITableViewHeaderFooterView 类型的分区头或分区尾视图
    public func cn_registerSectionHeaderFooterView(cls: AnyClass) {
        register(cls, forHeaderFooterViewReuseIdentifier: String(describing: cls))
    }

    // 注册带标识符的 UITableViewHeaderFooterView 类型的分区头或分区尾视图
    public func cn_registerSectionHeaderFooterView(cls: AnyClass, withIdentifier identifier: String) {
        register(cls, forHeaderFooterViewReuseIdentifier: identifier)
    }

    // 重用 UITableViewHeaderFooterView 类型的分区头或分区尾视图
//    public func cn_dequeueReusableSectionHeaderFooterView<T>(cls: T.Type) -> T where T: UITableViewHeaderFooterView {
//        guard let view = dequeueReusableHeaderFooterView(withIdentifier: String(describing: cls)) as? T else {
//            fatalError("Unable to dequeue header/footer view with identifier: \(String(describing: cls))")
//        }
//        return view
//    }
//
//    // 重用带标识符的 UITableViewHeaderFooterView 类型的分区头或分区尾视图
//    public func cn_dequeueReusableSectionHeaderFooterView<T>(withIdentifier identifier: String) -> T where T: UITableViewHeaderFooterView {
//        guard... let view = dequeueReusableHeaderFooterView(withIdentifier: identifier) as? T else {
//            fatalError("Unable to dequeue header/footer view with identifier: \(identifier)")
//        }
//        return view
//    }
    
    
//    func cn_dequeueReusableSectionHeaderFooterView<T: UITableViewHeaderFooterView> (cls: T.Type) -> T {
//        guard let headerFooterView = self.dequeueReusableHeaderFooterView(withIdentifier: "\(cls)") as? T else {
//            fatalError("出错了,请检查注册方法")
//        }
//        
//        return headerFooterView
//    }
//    
//    // TODO: 获取SectionHeaderFooterView 使用字符串作为标识符
//    ///
//    ///
//    ///
//    func cn_dequeueReusableSectionHeaderFooterView<T: UITableViewHeaderFooterView> (withIdentifier: String) -> T {
//        guard let headerFooterView = self.dequeueReusableHeaderFooterView(withIdentifier: withIdentifier) as? T else {
//            fatalError("出错了,请检查注册方法")
//        }
//        return headerFooterView
//    }

    // 滚动到表格顶部
    public func cn_scrollToTop(animated: Bool = true) {
        let indexPath = IndexPath(row: 0, section: 0)
        scrollToRow(at: indexPath, at: .top, animated: animated)
    }

    // 滚动到表格底部
    public func cn_scrollToBottom(animated: Bool = true) {
        let lastSection = numberOfSections - 1
        guard lastSection >= 0 else { return }
        let lastRow = numberOfRows(inSection: lastSection) - 1
        guard lastRow >= 0 else { return }
        let indexPath = IndexPath(row: lastRow, section: lastSection)
        scrollToRow(at: indexPath, at: .bottom, animated: animated)
    }

    // 判断指定的索引路径是否有效
    public func cn_isValidIndexPath(_ indexPath: IndexPath) -> Bool {
        let lastSection = numberOfSections - 1
        let lastRow = numberOfRows(inSection: lastSection) - 1
        return indexPath.section >= 0 && indexPath.section <= lastSection && indexPath.row >= 0 && indexPath.row <= lastRow
    }

    // 安全地滚动到指定的行
    public func cn_safeScrollToRow(at indexPath: IndexPath, at scrollPosition: UITableView.ScrollPosition, animated: Bool) {
        guard cn_isValidIndexPath(indexPath) else { return }
        scrollToRow(at: indexPath, at: scrollPosition, animated: animated)
    }
}
